/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2013-11-30         luwei
 */

package com.tianci.appstore.ui.widget;

import android.content.Context;
import android.util.SparseArray;
import android.view.View;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.RelativeLayout;

import com.coocaa.x.framework.utils.LogUtils;
import com.tianci.appstore.ui.widget.SkyBaseAdapter.ObserverListener;

import java.util.ArrayList;
import java.util.List;

public class SkyCustomLayout extends RelativeLayout implements ObserverListener {

    private SparseArray<Integer> mBlockMap = new SparseArray<Integer>();
    private SparseArray<Integer> mFocusViewPos = new SparseArray<Integer>();
    private List<BlockData> mBlockNum = null;
    private int mRow = 3;
    private int mCol = 4;
    private int mVerticalSpace = 30;
    private int mHorizontalSpace = 30;
    private int mBlockWidth = 200;
    private int mBlockHeight = 200;
    private int mMarginLeft = 0;
    private int mMarginTop = 0;
    private int mMarginRight = 0;
    private int mMarginBottom = 0;
    private int mBlockShadowX = 0;
    private int mBlockShdowY = 0;
    private SkyBaseAdapter mAdapter = null;
    private static final int INIT_ID = 0x0fff0100;
    private static int mInitId = INIT_ID;
    private List<View> mChildViews = new ArrayList<View>();
    private Context mContext = null;

    public SkyCustomLayout(Context context, float div) {
        super(context);
        this.mContext = context;
    }

    public static class BlockData {
        public int mRowNum = 0;
        public int mColNum = 0;
        public int mMarginLeft = 0;
        public int mMarginRight = 0;
        public int mMarginBottom = 0;
        public int mMarginTop = 0;
        public int mWidth = 0;
        public int mHeight = 0;
        public int[] mBlock = null;
        public boolean[] mTurnPage = null;
    }

    public static class CustomLayoutParams {
        public int mRow = 3;
        public int mCol = 4;
        public int mVerticalSpace = 30;
        public int mHorizontalSpace = 30;
        public int mBlockWidth = 200;
        public int mBlockHeight = 200;
        public int mMarginRight = 0;
        public int mMarginBottom = 0;
        public int mMarginLeft = 0;
        public int mMarginTop = 0;
        public int mBlockShadowX = 0;
        public int mBlockShdowY = 0;

    }

    public void setBlockDatas(List<BlockData> nums) {
        this.mBlockNum = nums;
    }

    public void setVerticalSpace(int space) {
        this.mVerticalSpace = space;
    }

    public void setHorizontalSpace(int space) {
        this.mHorizontalSpace = space;
    }

    public void setCustomLayoutParams(CustomLayoutParams params) {
        this.mRow = params.mRow;
        this.mCol = params.mCol;
        this.mVerticalSpace = params.mVerticalSpace;
        this.mHorizontalSpace = params.mHorizontalSpace;
        this.mBlockWidth = params.mBlockWidth;
        this.mBlockHeight = params.mBlockHeight;
        this.mMarginLeft = params.mMarginLeft;
        this.mMarginTop = params.mMarginTop;
        this.mMarginRight = params.mMarginRight;
        this.mMarginBottom = params.mMarginBottom;
        this.mBlockShadowX = params.mBlockShadowX;
        this.mBlockShdowY = params.mBlockShdowY;
    }

    public void setMargin(int left, int top, int right, int bottom) {
        this.mMarginLeft = left;
        this.mMarginTop = top;
        this.mMarginRight = right;
        this.mMarginBottom = bottom;
    }

    public void setChildViews(List<View> views) {
        this.mChildViews = views;
        removeAllViews();
    }

    public List<View> getChildViews() {
        return this.mChildViews;
    }

    public void setAdapter(SkyBaseAdapter adapter) {
        this.mAdapter = adapter;
        mAdapter.registObserver(this);
    }

    public int getCols() {
        return mCol;
    }

    public int getRows() {
        return mRow;
    }

    public int getBlockFirstPos(int index) {
        return mBlockNum.get(index).mBlock[0];
    }

    public int getBlockViewPos(int index) {
        try {
            return mFocusViewPos.get(index);
        } catch (Exception e) {
            return -1;
        }
    }

    public void setBlockSize(int width, int height) {
        this.mBlockWidth = width;
        this.mBlockHeight = height;
    }

    public void setBlockNum(int row, int col) {
        this.mRow = row;
        this.mCol = col;
    }

    public void setAnimation(int id) {
        AnimationSet set = new AnimationSet(true);
        set.addAnimation(AnimationUtils.loadAnimation(mContext, id));
        LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);
        controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
    }

    private void divideLayout() {
        BlockData tmpData = null;
        View tmpView = null;
        mFocusViewPos.clear();
        int i = 0;
        int count = mAdapter.getCount();
        for (BlockData block : mBlockNum) {
            View tempView = null;
            if (i < mChildViews.size()) {
                tempView = mChildViews.get(i);
            }
            View view = null;
            if (i < count) {
                view = mAdapter.getView(i, tempView, block.mTurnPage);
                for (Integer value : block.mBlock) {
                    mBlockMap.put(value, view.getId());
                    mFocusViewPos.put(value, i);
                }
            }
            if (count > getChildCount() && i >= getChildCount()) {
                if (mChildViews.size() > i && mChildViews.get(i) != null) {
                    addView(mChildViews.get(i));
                    for (Integer value : block.mBlock) {
                        mBlockMap.put(value, mChildViews.get(i).getId());
                        mFocusViewPos.put(value, i);
                    }
                }
            }
            i++;
            if (tempView == null && view != null) {
                int widthParams = block.mWidth;
                if (widthParams == 0) {
                    widthParams = block.mColNum * mBlockWidth + (block.mColNum - 1)
                            * mHorizontalSpace + 2 * mBlockShadowX;
                } else {
                    widthParams = block.mWidth;
                }

                int heigthParams = block.mHeight;
                if (heigthParams == 0) {
                    heigthParams = block.mRowNum * mBlockHeight + (block.mRowNum - 1)
                            * mVerticalSpace + 2 * mBlockShdowY;
                }
                view.setId(mInitId++);
                LogUtils.d("the position " + i + " the id is" + view.getId());
                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(widthParams,
                        heigthParams);
                if (block.mBlock[0] == 0) {
                    params.setMargins(block.mMarginLeft + mMarginLeft, block.mMarginTop + mMarginTop, block.mMarginRight,
                            block.mMarginBottom);
                } else if (block.mBlock[0] < mCol) {
                    params.setMargins(mHorizontalSpace + block.mMarginLeft - 2 * mBlockShadowX, block.mMarginTop + mMarginTop, block.mMarginRight,
                            block.mMarginBottom);
                } else if (block.mBlock[0] % mCol == 0) {
                    params.setMargins(block.mMarginLeft + mMarginLeft, mVerticalSpace
                            + block.mMarginTop - 2 * mBlockShdowY, block.mMarginRight, block.mMarginBottom);
                } else {
                    params.setMargins(mHorizontalSpace + block.mMarginLeft - 2 * mBlockShadowX, mVerticalSpace
                            + block.mMarginTop - 2 * mBlockShdowY, block.mMarginRight, block.mMarginBottom);
                }
                if (mBlockMap.size() > 0) {
                    if (block.mBlock[0] % mCol != 0) {
                        int id = 0;
                        if (mBlockMap.get(block.mBlock[0] - 1) == null) {
                            id = mBlockMap.get(block.mBlock[0] - mCol);
                        } else {
                            id = mBlockMap.get(block.mBlock[0] - 1);
                        }
                        params.addRule(RelativeLayout.RIGHT_OF, id);
                    }
                    if (block.mBlock[0] - mCol >= 0) {
                        int id = mBlockMap.get(block.mBlock[0] - mCol);
                        params.addRule(RelativeLayout.BELOW, id);
                    }
                }
                view.setLayoutParams(params);
                for (Integer value : block.mBlock) {
                    mBlockMap.put(value, view.getId());
                    mFocusViewPos.put(value, i - 1);
                }
                addView(view);
                mChildViews.add(view);
                tmpData = block;
                tmpView = view;
            }
        }
        setBootListNextFocusDown(count);
        hideItems(count);
        requestLayout();
    }

    public void setBootListNextFocusDown(int count) {
        if (count > 1 && count % mCol == 1) {
            if (getChildAt(count - 2) != null && getChildAt(count - 1) != null)
                getChildAt(count - 2).setNextFocusDownId(getChildAt(count - 1).getId());
        }
    }

    private void hideItems(int count) {
        if (count < mChildViews.size()) {
            for (int i = count; i < mChildViews.size(); i++) {
                View view = mChildViews.get(i);
                if (view != null) {
                    removeView(view);
                }

            }
        }
    }


    public int getMaxChildSize() {
        return mCol * mRow;
    }

    public SkyBaseAdapter getAdapter() {
        return mAdapter;
    }

    @Override
    public void onChanaged() {
        divideLayout();
    }

    public boolean setFocusPos(int pos, boolean focus) {
        if (pos < mChildViews.size()) {
            View view = mChildViews.get(pos);
            if (view != null) {
                if (focus) {
                    view.requestFocus();
                } else {
                    view.clearFocus();
                }
            }
        } else {
            if (mChildViews.size() > 0) {
                if (focus) {
                    mChildViews.get(mChildViews.size() - 1).requestFocus();
                } else {
                    mChildViews.get(mChildViews.size() - 1).clearFocus();
                }
            } else {
                return false;
            }
        }
        return true;
    }

    public boolean isItemFocus() {
        for (View view : mChildViews) {
            if (view.isFocused()) {
                return true;
            }
        }
        return false;
    }
}
